class Vec {
  x: number;
  y: number;

  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }

  plus(oVec: Vec) {
    return new Vec(this.x + oVec.x, this.y + oVec.y);
  }

  minus(oVec: Vec) {
    return new Vec(this.x - oVec.x, this.y - oVec.y);
  }

  get length() {
    return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
  }

  toString() {
    return `Vector: x-${this.x} y-${this.y}`;
  }
}

class Group {
  store: Array<any>;
  cursor: number;
  constructor() {
    this.store = [];
    this.cursor = 0;
  }

  add(e) {
    if (!this.has(e)) {
      this.store.push(e);
    }
  }

  delete(e) {
    if (this.has(e)) {
      this.store.splice(this.store.indexOf(e), 1);
    }
  }

  has(e) {
    if (this.store.length == 0) {
      return false;
    } else {
      for (let ele of this.store) {
        if (ele === e) {
          return true;
        }
      }
      return false;
    }
  }

  static from(iterable) {
    const group = new Group();
    for (let e of iterable) {
      group.add(e);
    }
    return group;
  }

  next() {
    if (this.store.length == 0) return { done: true };
    if (this.cursor == this.store.length) return { done: true };
    return { value: this.store[this.cursor++], done: false };
  }
}

class GroupIterator {
  group: Group;
  cursor = 0;
  constructor(group: Group) {
    this.group = group;
  }
  next() {
    if (this.group.store.length == 0) return { done: true };
    if (this.group.cursor == this.group.store.length) return { done: true };
    return { value: this.group.store[this.cursor++], done: false };
  }
}

Group.prototype[Symbol.iterator] = function () {
  return new GroupIterator(this);
};

class Solution {
  testVec(vec1, vec2) {
    console.log(vec1, "\n", vec2);
    console.log(vec1.length);
    console.log(vec2.length);
    console.log(vec1.plus(vec2));
    console.log(vec1.minus(vec2));
  }

  testGroup(arr) {
    const group = Group.from(arr);
    for (let e of group.store) {
      console.log(e);
    }
  }
}

const sol = new Solution();
const vec1 = new Vec(1, 2);
const vec2 = new Vec(-1, -2);
sol.testVec(vec1, vec2);
sol.testGroup([1, 2, 2, "str", "str", 5, 6, 67, 7, 7]);

// 一个对象原型中有的方法，但是对象自身有同名方法覆盖了这个方法，如果想调用原型中的方法怎么办
// 1. 直接将对象的原型对象拿到，再调用对应的方法
// 2. 用符号来替代掉这个和原型方法同名的方法，再进行调用
